package tt.dz.order.util.thirdrecord;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.ApplicationContext;

import tt.dz.order.dao.SysApplicationContextAware;
import tt.dz.order.util.OrderConstant.OrderPayChannelCode;

/**
 * 
 * 
 * @name 第三方支付查询工厂
 * @author Anson
 * @version 1.0
 * @summary 贫血型的工厂模式<br>
 *          bean的实例化方式不能扩展，若要扩展这块实例化方式，则采用抽象的工厂模式可实现当前方式<br>
 *          根据当前业务，贫血模式即可满足需求<br>
 *          单例模式{@linkplain ThirdRecordQueryFactory#INSTANCE() }
 * @desc 查询bean实例化通过spring管理，这里做了一次小缓存<br>
 *       通过当前类中{@linkplain ThirdRecordQueryFactory#clazzs}规定了当前工厂产生的查询bean的类型
 *       <br>
 *       查询初始化存在{@link ThirdRecordQueryFactory#init()}
 *
 */
public class ThirdRecordQueryFactory {

	private Map<OrderPayChannelCode, ThirdRecordQuery> queryMap = new HashMap<OrderPayChannelCode, ThirdRecordQuery>();
	private static List<Class<? extends ThirdRecordQuery>> clazzs = new ArrayList<Class<? extends ThirdRecordQuery>>();
	static {
		ThirdRecordQueryFactory.clazzs.add(AliPayThirdRecordQuery.class);
		ThirdRecordQueryFactory.clazzs.add(WeiXinPayThirdRecordQuery.class);
		ThirdRecordQueryFactory.clazzs.add(YouBeiPayThirdRecordQuery.class);
	}
	public static class InnerThirdRecordQueryFactory {
		private static ThirdRecordQueryFactory factory = new ThirdRecordQueryFactory();
	}

	public static final ThirdRecordQueryFactory INSTANCE() {
		return InnerThirdRecordQueryFactory.factory;
	}

	public ThirdRecordQueryFactory() {
		super();
		init();
	}

	/**
	 * 从spring容器中查询当前的管理的bean
	 */
	private void init() {
		ApplicationContext applicationContext = SysApplicationContextAware.getApplication();
		ThirdRecordQuery query = null;
		if (applicationContext != null) {
			for (Class<? extends ThirdRecordQuery> requiredType : clazzs) {
				if (requiredType == null) {
					continue;
				}
				query = applicationContext.getBean(requiredType);
				if (query == null) {
					continue;
				}
				this.queryMap.put(query.getThirdChannelCode(), query);
			}
		}
	}

	public ThirdRecordQuery get(OrderPayChannelCode code) {
		return this.queryMap.get(code);
	}
}
